﻿using Kimd.Logic;
using Kimd.Machine;
using Kimd.Motion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ExplorerBar;
using WorkStation.Common;
using System.Runtime.ExceptionServices;
using Kimd.Common;

namespace WorkStation.Logic
{
    /// <summary>
    /// 该逻辑实现上料的取料和放精定位动作
    /// 名字:取料逻辑
    /// </summary>
    public class FeedHeaderLogic : FlowBase
    {
        private FeedHeaderStatus _status;
        public Header3Position HeaderPos { get; set; }
        //axis
        private Axis _x;
        private Axis _y;
        private Axis _precisionY;
        private Axis _z;
        private Axis _r;
        //cylinder
        private List<Cylinder> _nozzles;
        private List<Cylinder> _vacs;
        private List<Cylinder> _revVacs;
        private List<Cylinder> _precisionVacs;
        private List<Cylinder> _precisionRevVacs;
        private List<Cylinder> _precisionPositions;
        private Cylinder _changeCylinder;
        //sensor
        private List<Sensor> _vacSense;
        //tray
        private Dictionary<int, (List<int>, List<int>)> _getIndex2Nozzles;
        private Tray _halfTrayFirst;
        private Tray _halfTraySecond;
        private Tray _visionTray;
        private Tray _nozzleTray;
        public FeedHeaderLogic(string flowName, FlowManager flowmanager)
            : base(flowName, flowmanager)
        {
            _x = MachineResource.Instance.MachineAxis["上料移载X轴"];
            _y = MachineResource.Instance.MachineAxis["上料仓Y轴"];
            _precisionY = MachineResource.Instance.MachineAxis["精定区Y轴"];
            _z = MachineResource.Instance.MachineAxis["上料移载Z轴"];
            _r = MachineResource.Instance.MachineAxis["上料移载U轴"];

            _nozzles = new List<Cylinder>()
            {
                MachineResource.Instance.MachineCylinder["上料移载取料气缸1下降V"],
                MachineResource.Instance.MachineCylinder["上料移载取料气缸2下降V"],
                MachineResource.Instance.MachineCylinder["上料移载取料气缸3下降V"],
                MachineResource.Instance.MachineCylinder["上料移载取料气缸4下降V"],
            };
            _vacs = new List<Cylinder>()
            {
                MachineResource.Instance.MachineCylinder["上料移载取料1真空吸"],
                MachineResource.Instance.MachineCylinder["上料移载取料2真空吸"],
                MachineResource.Instance.MachineCylinder["上料移载取料3真空吸"],
                MachineResource.Instance.MachineCylinder["上料移载取料4真空吸"],
            };
            _revVacs = new List<Cylinder>()
            {
                MachineResource.Instance.MachineCylinder["上料移载取料1破真空"],
                MachineResource.Instance.MachineCylinder["上料移载取料2破真空"],
                MachineResource.Instance.MachineCylinder["上料移载取料3破真空"],
                MachineResource.Instance.MachineCylinder["上料移载取料4破真空"],
            }; 
            _precisionVacs = new List<Cylinder>()
            {
                MachineResource.Instance.MachineCylinder["精定位1真空吸"],
                MachineResource.Instance.MachineCylinder["精定位2真空吸"],
                MachineResource.Instance.MachineCylinder["精定位3真空吸"],
                MachineResource.Instance.MachineCylinder["精定位4真空吸"],
            };
            _precisionRevVacs = new List<Cylinder>()
            {
                MachineResource.Instance.MachineCylinder["精定位1破真空"],
                MachineResource.Instance.MachineCylinder["精定位2破真空"],
                MachineResource.Instance.MachineCylinder["精定位3破真空"],
                MachineResource.Instance.MachineCylinder["精定位4破真空"],
            };
            _precisionPositions = new List<Cylinder>()
            {
                MachineResource.Instance.MachineCylinder["精定位1定位气缸伸出V"],
                MachineResource.Instance.MachineCylinder["精定位2定位气缸伸出V"],
                MachineResource.Instance.MachineCylinder["精定位3定位气缸伸出V"],
                MachineResource.Instance.MachineCylinder["精定位4定位气缸伸出V"],
            };
            _changeCylinder = MachineResource.Instance.MachineCylinder["上料移栽变距气缸动点V"];
            _vacSense = new List<Sensor>()
            {
                MachineResource.Instance.MachineSensor["上料移载取料1真空达到"],
                MachineResource.Instance.MachineSensor["上料移载取料2真空达到"],
                MachineResource.Instance.MachineSensor["上料移载取料3真空达到"],
                MachineResource.Instance.MachineSensor["上料移载取料4真空达到"],
            };
            _vacSense = new List<Sensor>()
            {
                MachineResource.Instance.MachineSensor["精定位1真空到位"],
                MachineResource.Instance.MachineSensor["精定位2真空到位"],
                MachineResource.Instance.MachineSensor["精定位3真空到位"],
                MachineResource.Instance.MachineSensor["精定位4真空到位"],
            };
            //半盘 取 10次 可以取完
            _halfTrayFirst = new Tray(1, 10);
            _halfTraySecond = new Tray(1, 10);
            _getIndex2Nozzles = new Dictionary<int, (List<int>, List<int>)>();
            _getIndex2Nozzles.Add(1, (new List<int>() { 1, 2, 3, 4 }, new List<int>()));
            _getIndex2Nozzles.Add(2, (new List<int>() { 5 }, new List<int>() { 6, 7, 8 }));
            _getIndex2Nozzles.Add(3, (new List<int>() { 9, 10 }, new List<int>() { 11, 12 }));
            _getIndex2Nozzles.Add(4, (new List<int>() { 13, 14, 15 }, new List<int>() { 16 }));
            _getIndex2Nozzles.Add(5, (new List<int>(), new List<int>() { 17, 18, 19, 20 }));
            _visionTray = new Tray(16, 5);
            _nozzleTray = new Tray(1, 4);

            RegisterDirectSignal("前半取完");
            RegisterDirectSignal("后半取完");
            RegisterDirectSignal("上料头回零完成");
            RegisterDirectSignal("Z轴已抬起");
            RegisterDirectSignal("精定位完成");
            RegisterDirectSignal("x回零完成");
        }
        public (List<int>, List<int>) ChooseNozzles(bool isFirstHalf, out int getIndex)
        {
            getIndex = isFirstHalf ? _halfTrayFirst.Helper.GetFirstIndex(CellStatus.HasProduct) : _halfTraySecond.Helper.GetFirstIndex(CellStatus.HasProduct);
            //半盘还没取完的话
            if (getIndex != -1)
            {
                List<int> firstGet = new List<int>();
                List<int> secondGet = new List<int>();
                (firstGet, secondGet) = _getIndex2Nozzles[(getIndex % 5 + 1)];
                int index = 0;
                if (isFirstHalf && getIndex < 5)
                    index = 0;
                else if(isFirstHalf && getIndex >= 5)
                    index = 1;
                else if (!isFirstHalf && getIndex < 5)
                    index = 2;
                else if(!isFirstHalf && getIndex >= 5)
                    index = 3;
                return (firstGet.Select(x => x + 20 * index).ToList(), secondGet.Select(x => x + 20 * index).ToList());
            }
            return (new List<int>(), new List<int>());
        }

        public override void Calibrate()
        {
            base.Calibrate();
        }

        public override void Home()
        {
            if (!CheckFlowCondition()) return;
            MultiCylinderOperate(_nozzles, 5000, new List<bool>() { false, false, false, false });
            if (!CheckFlowCondition()) return;
            SingleCylinderOperate(_changeCylinder, 5000, false);
            if (!CheckFlowCondition()) return;
            //TODO 吸嘴真空判断
            _revVacs.ForEach(v => v.Off());
            for (int i = 0; i < _vacs.Count; i++)
            {
                if (!_vacSense[i].WaitOn())
                {
                    _vacs[i].Off();
                }
            }

            _precisionRevVacs.ForEach(v => v.Off());
            _precisionVacs.ForEach(v => v.Off());

            _z.ClearAlarm();
            Thread.Sleep(200);
            _z.SetServoOn();
            Thread.Sleep(200);
            _x.ClearAlarm();
            Thread.Sleep(200);
            _x.SetServoOn();
            Thread.Sleep(200);
            _r.ClearAlarm();
            Thread.Sleep(200);
            _r.SetServoOn();
            Thread.Sleep(200);

            if(!GlobalVariable.IsSystemAlreadyHome)
                SingleAxisGoHome(_z);
            else
                SingleAxisMove2Point(_z, 0);
            if (!CheckFlowCondition()) return;
            SetSignal("Z轴已抬起");
            SingleAxisMove2Point(_z, "R轴回零位");
            if (!CheckFlowCondition()) return;
            if (!GlobalVariable.IsSystemAlreadyHome)
                AxisGoHomeSimultaneously(new List<Axis>() { _x, _r });
            else
                AxisMoveSimultaneously(new List<Axis>() { _x, _r }, new List<double>() { 0, 0 });
            if (!CheckFlowCondition()) return;
            SetSignal("x回零完成");
            if (!CheckFlowCondition()) return;
            SingleAxisMove2Point(_r, "待机位");
            if (!CheckFlowCondition()) return;

            checkProductStatus();

            precisionFinish = true;
            GlobalVariable.PrecisionTray.Helper.NewEmptyTray();

            _status = FeedHeaderStatus.CaptureTray;
        }

        public override void Init(out string errInfo)
        {
            base.Init(out errInfo);
        }

        public override void InSingleRunMode()
        {
            base.InSingleRunMode();
        }

        List<bool> nozzleStatusFirst = null;
        List<bool> nozzleStatusSecond = null;
        List<double> posFirst = null;
        List<double> posSecond = null;
        string zGetPosFirst = "";
        string zGetPosSecond = "";
        bool nowGetFirst = false;
        bool precisionFinish = true;
        Task t;
        public override void Method()
        {
            if (!CheckFlowCondition()) return;

            switch (_status)
            {
                case FeedHeaderStatus.CaptureTray:

                    WaitForSignal("上Tray模组", "取料位置有Tray");
                    //Z轴抬起
                    SingleAxisMove2Point(_z, "安全位置");
                    if (!CheckFlowCondition()) return;
                    AxisMoveSimultaneously(_x, _r, "拍照位");
                    HeaderPos = Header3Position.Get;
                    if (!CheckFlowCondition()) return;
                    SingleAxisMove2Point(_z, "拍照位");
                    if (!CheckFlowCondition()) return;
                    if (GlobalVariable.IsDryRun)
                        Thread.Sleep(500);
                    _halfTrayFirst.Helper.NewFullTray();
                    _halfTraySecond.Helper.NewFullTray();
                    _visionTray.Helper.NewFullTray();   
                    //TODO 拍照
                    _status = FeedHeaderStatus.GetProduct1;

                    break;

                case FeedHeaderStatus.WaitSecond:
                    WaitForSignal("上Tray模组", "可以取后半");
                    if (!CheckFlowCondition()) return;
                    nowGetFirst = false;
                    _status = FeedHeaderStatus.GetProduct2;
                    break;

                case FeedHeaderStatus.GetProduct1:
                case FeedHeaderStatus.GetProduct2:
                    //不为空可取料
                    List<int> first = new List<int>();
                    List<int> second = new List<int>();
                    nowGetFirst = _status == FeedHeaderStatus.GetProduct1;
                    (first, second) = ChooseNozzles(nowGetFirst, out int getIndex);
                    if (first.Count == 0 && second.Count == 0)
                    {
                        if (_status == FeedHeaderStatus.GetProduct1)
                        {
                            SetSignal("前半取完");
                            WaitForSignal("上Tray模组", "可以取后半");
                            if (!CheckFlowCondition()) return;
                            _status = FeedHeaderStatus.GetProduct2;
                        }
                        else
                        {
                            SetSignal("后半取完");
                            if (!CheckFlowCondition()) return;
                            _status = FeedHeaderStatus.CaptureTray;
                        }
                    }
                    else
                    {
                        if (GetNozzleStatusAndPosition(nowGetFirst, 
                                                       first, second, 
                                                       out nozzleStatusFirst, out nozzleStatusSecond,
                                                       out posFirst, out posSecond,
                                                       out zGetPosFirst, out zGetPosSecond))
                        {
                            //Z轴抬起
                            SingleAxisMove2Point(_z, "安全位置");
                            if (!CheckFlowCondition()) return;
                            //第一list里面有取料点位，且视觉判定下来有需要取料的
                            if (posFirst.Count != 0 && nozzleStatusFirst.Any(c => c) && !string.IsNullOrEmpty(zGetPosFirst))
                            {
                                AxisMoveSimultaneously(new List<Axis>() { _x, _y }, posFirst);
                                if (!CheckFlowCondition()) return;
                                NozzleGetProductExt(_z, _nozzles, _vacs, _vacSense, null, null,
                                                    zGetPosFirst, "安全位置", "",
                                                    5000, delayAfterOpenVac: 100, delayBeforeVacCheck: 100,
                                                    GlobalVariable.IsDryRun,
                                                    nozzleStatusFirst);
                                if (!CheckFlowCondition()) return;

                                //交换料状态
                                for (int i = 0; i < nozzleStatusFirst.Count; i++)
                                {
                                    if (nozzleStatusFirst[i])
                                        _nozzleTray.Helper.SetCellStatus(i, CellStatus.HasProduct);
                                }
                            }
                            if (posSecond.Count != 0 && nozzleStatusSecond.Any(c => c) && !string.IsNullOrEmpty(zGetPosSecond))
                            {
                                AxisMoveSimultaneously(new List<Axis>() { _x, _y }, posSecond);
                                if (!CheckFlowCondition()) return;
                                NozzleGetProductExt(_z, _nozzles, _vacs, _vacSense, null, null,
                                                    zGetPosSecond, "安全位置", "",
                                                    5000, delayAfterOpenVac: 100, delayBeforeVacCheck: 100,
                                                    GlobalVariable.IsDryRun,
                                                    nozzleStatusSecond);
                                if (!CheckFlowCondition()) return;

                                //交换料状态
                                for (int i = 0; i < nozzleStatusSecond.Count; i++)
                                {
                                    if (nozzleStatusSecond[i])
                                        _nozzleTray.Helper.SetCellStatus(i, CellStatus.HasProduct);
                                }
                            }
                            _status = FeedHeaderStatus.PutProduct;
                        }
                        if (getIndex != -1 && nowGetFirst)
                            _halfTrayFirst.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                        if (getIndex != -1 && !nowGetFirst)
                            _halfTraySecond.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                        (first, second) = ChooseNozzles(nowGetFirst, out getIndex);
                        if (first.Count == 0 && second.Count == 0)
                        {
                            if (nowGetFirst)
                            {
                                SetSignal("前半取完");
                            }
                            else
                            {
                                SetSignal("后半取完");
                            }
                        }
                    }

                    break;

                case FeedHeaderStatus.PutProduct:
                    //上一轮的精定位动作至少要结束了吧
                    while (!precisionFinish && !IsBreak())
                    {
                        Thread.Sleep(10);
                    }
                    precisionFinish = false;
                    if (!CheckFlowCondition()) return;
                    //首先等到精定位没料，才放料
                    while (GlobalVariable.PrecisionTray.Helper.Any(c => c.Status == CellStatus.HasProduct) && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    //请求使用精定位区域
                    Monitor.Enter(GlobalVariable.PrecisionAreaLock);
                    HeaderPos = Header3Position.Precision;
                    //Z轴抬起
                    SingleAxisMove2Point(_z, "安全位置");
                    if (!CheckFlowCondition()) return;
                    _changeCylinder.On();
                    AxisMoveSimultaneously(_x, _precisionY, _r, "精定位放料位置");
                    if (!CheckFlowCondition()) return;
                    SingleCylinderWait(_changeCylinder, 5000, true);
                    if (!CheckFlowCondition()) return;
                    HeaderPos = Header3Position.Precision;
                    //放精定位
                    NozzlePutProductExt(_z, _nozzles, _vacs, _revVacs, _precisionVacs,
                                        "精定位放料位置", "精定位放料位置", 0, 10,
                                        5000, delayBeforeNozzleUp: 100,
                                        _nozzleTray.Helper.Select(n => n.Status == CellStatus.HasProduct).ToList());
                    if (!CheckFlowCondition()) return;
                    //异步进行精定位动作
                    t = new Task(() =>
                    {
                        //置位状态，精定位有料,精定位有料的话，代表着feedtester可以进入
                        for (int i = 0; i < _nozzleTray.Helper.ToList().Count; i++)
                        {
                            if (_nozzleTray.Helper.GetCell(i).Status == CellStatus.HasProduct &&
                                GlobalVariable.PrecisionTray.Helper.GetCell(i).Status == CellStatus.NoProduct)
                            {
                                GlobalVariable.PrecisionTray.Helper.SetCellStatus(i, CellStatus.HasProduct);
                                GlobalVariable.PrecisionTray.Helper.SetCellBarcode(i, "");
                                GlobalVariable.PrecisionTray.Helper.SetCellResult(i, TestResult.NoTest);

                                _nozzleTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                                _nozzleTray.Helper.SetCellBarcode(i, string.Empty);
                                _nozzleTray.Helper.SetCellResult(i, TestResult.NoTest);
                            }
                        }

                        _precisionPositions.ForEach(c => c.On());
                        Thread.Sleep(1000);
                        _precisionPositions.ForEach(c => c.Off());
                        _precisionVacs.ForEach(v => v.Off());
                        precisionFinish = true;

                        SetSignal("精定位完成");

                        if (!CheckFlowCondition()) return;
                    });
                    t.Start();
                    //往回走的时候，即可以让出精定位区
                    //Monitor.Exit(GlobalVariable.PrecisionAreaLock);
                    HeaderPos = Header3Position.Get;
                    if (!CheckFlowCondition()) return;

                    #region 走到下一波的预备位置
                redecide:
                    //如果刚刚是在取前一半
                    (first, second) = ChooseNozzles(nowGetFirst, out getIndex);
                    if (first.Count == 0 && second.Count == 0)
                    {
                        if (nowGetFirst)
                        {
                            //确保动起来以后，方可让出精定位区域
                            AxisMoveSimultaneously(_x, _r, $"{"上料矩阵吸嘴1后半"}-{0}-{0}", lockObj: GlobalVariable.PrecisionAreaLock);
                            _status = FeedHeaderStatus.WaitSecond;
                        }
                        else
                        {
                            //确保动起来以后，方可让出精定位区域
                            AxisMoveSimultaneously(_x, _r, "拍照位", lockObj: GlobalVariable.PrecisionAreaLock);
                            _status = FeedHeaderStatus.CaptureTray;
                        }
                    }
                    else
                    {
                        (first, second) = ChooseNozzles(nowGetFirst, out getIndex);
                        //走到前一半的取料位置
                        if (GetNozzleStatusAndPosition(nowGetFirst,
                                                        first, second,
                                                    out nozzleStatusFirst, out nozzleStatusSecond,
                                                    out posFirst, out posSecond,
                                                    out zGetPosFirst, out zGetPosSecond))
                        {
                            if(!string.IsNullOrEmpty(zGetPosFirst))
                                //确保动起来以后，方可让出精定位区域
                                AxisMoveSimultaneously(new List<Axis>() { _x, _y }, posFirst, lockObj: GlobalVariable.PrecisionAreaLock);
                            else if (!string.IsNullOrEmpty(zGetPosSecond))
                                //确保动起来以后，方可让出精定位区域
                                AxisMoveSimultaneously(new List<Axis>() { _x, _y }, posSecond, lockObj: GlobalVariable.PrecisionAreaLock);
                            if(nowGetFirst)
                                _status = FeedHeaderStatus.GetProduct1;
                            else
                                _status = FeedHeaderStatus.GetProduct2;
                        }
                        else
                            goto redecide;
                    }
                    #endregion

                    //这个地方才可以暂停
                    if (!CheckFlowCondition()) return;

                    break;
            }
        }
        public bool GetNozzleStatusAndPosition(bool isFirstHalf,
                                               List<int> first, List<int> second,
                                               out List<bool> nozzleStatusFirst, out List<bool> nozzleStatusSecond,
                                               out List<double> posFirst, out List<double> posSecond,
                                               out string zGetPosFirst, out string zGetPosSecond)
        {
            //结合视觉看下哪几个吸嘴要下
            nozzleStatusFirst = new List<bool>();
            nozzleStatusFirst = first.Select(x => _visionTray.Helper.GetCell(x - 1).Status == CellStatus.HasProduct).ToList();
            nozzleStatusSecond = new List<bool>();
            nozzleStatusSecond = second.Select(x => _visionTray.Helper.GetCell(x - 1).Status == CellStatus.HasProduct).ToList();
            //前提是都有可取的料
            posFirst = new List<double>();
            posSecond = new List<double>();
            zGetPosFirst = "";
            zGetPosSecond = "";
            string matrixName1 = isFirstHalf ? "上料矩阵吸嘴1" : "上料矩阵吸嘴1后半";
            string matrixName4 = isFirstHalf ? "上料矩阵吸嘴4" : "上料矩阵吸嘴4后半";
            if (nozzleStatusFirst.Any(c => c) || nozzleStatusSecond.Any(c => c))
            {
                //选择first的点位
                int firstchange = first.Find(x => x % 20 == 1 || x % 20 == 6 || x % 20 == 11 || x % 20 == 16);
                if (firstchange != 0)
                {
                    posFirst.Add(_x.MotionPosition[$"{matrixName1}-{firstchange % 40 / 5}-{0}"]);
                    posFirst.Add(_y.MotionPosition[$"{matrixName1}-{firstchange % 40 / 5}-{0}"]);
                    zGetPosFirst = $"{matrixName1}-{firstchange % 40 / 5}-{0}";
                    int count = 4 - nozzleStatusFirst.Count;
                    for (int i = 0; i < count; i++)
                    {
                        nozzleStatusFirst.Add(false);
                    }
                }
                else
                {
                    firstchange = first.Find(x => x % 20 == 0 || x % 20 == 5 || x % 20 == 10 || x % 20 == 15 || x % 20 == 20);
                    if (firstchange != 0)
                    {
                        posFirst.Add(_x.MotionPosition[$"{matrixName4}-{(firstchange / 5 - 1) % 8}-{0}"]);
                        posFirst.Add(_y.MotionPosition[$"{matrixName4}-{(firstchange / 5 - 1) % 8}-{0}"]);
                        zGetPosFirst = $"{matrixName4}-{(firstchange / 5 - 1) % 8}-{0}";
                        int count = 4 - nozzleStatusFirst.Count;
                        for (int i = 0; i < count; i++)
                        {
                            nozzleStatusFirst.Insert(0, false);
                        }
                    }
                }
                int secondchange = second.Find(x => x % 20 == 1 || x % 20 == 6 || x % 20 == 11 || x % 20 == 16);
                if (secondchange != 0)
                {
                    posSecond.Add(_x.MotionPosition[$"{matrixName1}-{secondchange % 40 / 5}-{0}"]);
                    posSecond.Add(_y.MotionPosition[$"{matrixName1}-{secondchange % 40 / 5}-{0}"]);
                    zGetPosSecond = $"{matrixName1}-{secondchange % 40 / 5}-{0}";
                    int count = 4 - nozzleStatusSecond.Count;
                    for (int i = 0; i < count; i++)
                    {
                        nozzleStatusSecond.Add(false);
                    }
                }
                else
                {
                    secondchange = second.Find(x => x % 20 == 0 || x % 20 == 5 || x % 20 == 10 || x % 20 == 15 || x % 20 == 20);
                    if (secondchange != 0)
                    {
                        posSecond.Add(_x.MotionPosition[$"{matrixName4}-{(secondchange / 5 - 1) % 8}-{0}"]);
                        posSecond.Add(_y.MotionPosition[$"{matrixName4}-{(secondchange / 5 - 1) % 8}-{0}"]);
                        zGetPosSecond = $"{matrixName4}-{(secondchange / 5 - 1) % 8}-{0}";
                        int count = 4 - nozzleStatusSecond.Count;
                        for (int i = 0; i < count; i++)
                        {
                            nozzleStatusSecond.Insert(0, false);
                        }
                    }
                }
                return true;
            }
            return false;
        }

        public void checkProductStatus()
        {
        restart:
            for (int i = 0; i < _vacSense.Count; i++)
            {
                if (_vacSense[i].WaitOn())
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.InfoAndPause, $"上料头上有料，请取走", this.Description, 0, "系统"));
                    //出错，停下所有线程
                    _flowManager.Pause();
                    //若为报错，需重新检测启动信号
                    WaitForStart();
                    if (!CheckFlowCondition()) return;
                    goto restart;
                }
            }
            //关闭所有真空
            _vacs.ForEach(v => v.Off());

            for (int i = 0; i < _vacSense.Count; i++)
            {
                if (_vacSense[i].WaitOn())
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.InfoAndPause, $"精定位上有料，请取走", this.Description, 0, "系统"));
                    //出错，停下所有线程
                    _flowManager.Pause();
                    //若为报错，需重新检测启动信号
                    WaitForStart();
                    if (!CheckFlowCondition()) return;
                    goto restart;
                }
            }
            //关闭所有真空
            _precisionVacs.ForEach(v => v.Off());
        }
        public override void OnStop()
        {
            base.OnStop();
        }

        public override bool PreStartCheck()
        {
            return base.PreStartCheck();
        }

        public override void SpotCheck()
        {
            base.SpotCheck();
        }
    }
    public enum FeedHeaderStatus
    {
        CaptureTray,
        GetProduct1,
        GetProduct2,
        PutProduct,
        Wait,
        WaitSecond,
    }

    public enum Header3Position
    {
        Get,
        Precision,
        Tester,
        NGBuffer,
        OK
    }
}
